<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>React知识点总结 | MyBlog</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/markdown-blog/favicon.ico">
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    
    <link rel="preload" href="/markdown-blog/assets/css/0.styles.25640b18.css" as="style"><link rel="preload" href="/markdown-blog/assets/js/app.4ad08097.js" as="script"><link rel="preload" href="/markdown-blog/assets/js/3.ddd67056.js" as="script"><link rel="preload" href="/markdown-blog/assets/js/1.7a25059f.js" as="script"><link rel="preload" href="/markdown-blog/assets/js/29.f6bd6a28.js" as="script"><link rel="prefetch" href="/markdown-blog/assets/js/10.f00be53f.js"><link rel="prefetch" href="/markdown-blog/assets/js/11.7ac2e99b.js"><link rel="prefetch" href="/markdown-blog/assets/js/12.f11c009c.js"><link rel="prefetch" href="/markdown-blog/assets/js/13.be750ad0.js"><link rel="prefetch" href="/markdown-blog/assets/js/14.09d576e3.js"><link rel="prefetch" href="/markdown-blog/assets/js/15.b4c1727e.js"><link rel="prefetch" href="/markdown-blog/assets/js/16.4890e6f7.js"><link rel="prefetch" href="/markdown-blog/assets/js/17.feac5f26.js"><link rel="prefetch" href="/markdown-blog/assets/js/18.b49467b1.js"><link rel="prefetch" href="/markdown-blog/assets/js/19.29b4407f.js"><link rel="prefetch" href="/markdown-blog/assets/js/20.9ee55973.js"><link rel="prefetch" href="/markdown-blog/assets/js/21.b6da110b.js"><link rel="prefetch" href="/markdown-blog/assets/js/22.c64d89ab.js"><link rel="prefetch" href="/markdown-blog/assets/js/23.1249a0d2.js"><link rel="prefetch" href="/markdown-blog/assets/js/24.858426bc.js"><link rel="prefetch" href="/markdown-blog/assets/js/25.1eaccce9.js"><link rel="prefetch" href="/markdown-blog/assets/js/26.6d8a66e7.js"><link rel="prefetch" href="/markdown-blog/assets/js/27.bef6e2f6.js"><link rel="prefetch" href="/markdown-blog/assets/js/28.1d169f61.js"><link rel="prefetch" href="/markdown-blog/assets/js/30.6b0a16e0.js"><link rel="prefetch" href="/markdown-blog/assets/js/31.3a6f1d19.js"><link rel="prefetch" href="/markdown-blog/assets/js/4.46f777c5.js"><link rel="prefetch" href="/markdown-blog/assets/js/5.db5e4405.js"><link rel="prefetch" href="/markdown-blog/assets/js/6.8b37b343.js"><link rel="prefetch" href="/markdown-blog/assets/js/7.cacb4248.js"><link rel="prefetch" href="/markdown-blog/assets/js/8.6174f008.js"><link rel="prefetch" href="/markdown-blog/assets/js/9.4f9a61ea.js">
    <link rel="stylesheet" href="/markdown-blog/assets/css/0.styles.25640b18.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container" data-v-1aefc0b4><div data-v-1aefc0b4><div id="loader-wrapper" class="loading-wrapper" data-v-d48f4d20 data-v-1aefc0b4 data-v-1aefc0b4><div class="loader-main" data-v-d48f4d20><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div><div data-v-d48f4d20></div></div> <!----> <!----></div> <div class="password-shadow password-wrapper-out" style="display:none;" data-v-25ba6db2 data-v-1aefc0b4 data-v-1aefc0b4><h3 class="title" data-v-25ba6db2 data-v-25ba6db2>MyBlog</h3> <p class="description" data-v-25ba6db2 data-v-25ba6db2></p> <label id="box" class="inputBox" data-v-25ba6db2 data-v-25ba6db2><input type="password" value="" data-v-25ba6db2> <span data-v-25ba6db2>Konck! Knock!</span> <button data-v-25ba6db2>OK</button></label> <div class="footer" data-v-25ba6db2 data-v-25ba6db2><span data-v-25ba6db2><i class="iconfont reco-theme" data-v-25ba6db2></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-25ba6db2>vuePress-theme-reco</a></span> <span data-v-25ba6db2><i class="iconfont reco-copyright" data-v-25ba6db2></i> <a data-v-25ba6db2><span data-v-25ba6db2>kasnars</span>
            
          <span data-v-25ba6db2>2021 - </span>
          2024
        </a></span></div></div> <div class="hide" data-v-1aefc0b4><header class="navbar" data-v-1aefc0b4><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/markdown-blog/" class="home-link router-link-active"><img src="/markdown-blog/wsq.webp" alt="MyBlog" class="logo"> <span class="site-name">MyBlog</span></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">Choose mode</h4> <ul class="color-mode-options"><li class="dark">dark</li><li class="auto active">auto</li><li class="light">light</li></ul></div></div></div> <div class="search-box"><i class="iconfont reco-search"></i> <input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/markdown-blog/" class="nav-link"><i class="iconfont reco-home"></i>
  主页
</a></div><div class="nav-item"><a href="/markdown-blog/timeline/" class="nav-link"><i class="iconfont reco-date"></i>
  时间轴
</a></div><div class="nav-item"><a href="/markdown-blog/tag/" class="nav-link"><i class="iconfont reco-tag"></i>
  标签
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>
      文档
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/theme-reco/" class="nav-link router-link-active"><i class="undefined"></i>
  前端知识点
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/computer/" class="nav-link"><i class="undefined"></i>
  计算机基础
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/others/" class="nav-link"><i class="undefined"></i>
  其他技术栈
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-category"></i>
      分类
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/个人作品/" class="nav-link"><i class="undefined"></i>
  个人作品
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/解决方案/" class="nav-link"><i class="undefined"></i>
  解决方案
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/BUG记录/" class="nav-link"><i class="undefined"></i>
  BUG记录
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/技术整理/" class="nav-link"><i class="undefined"></i>
  技术整理
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/前端总结/" class="nav-link"><i class="undefined"></i>
  前端总结
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>
      链接
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://gitee.com/kasnars" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-mayun"></i>
  Gitee
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://juejin.cn/user/2287450072292567" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-juejin"></i>
  稀土掘金
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask" data-v-1aefc0b4></div> <aside class="sidebar" data-v-1aefc0b4><div class="personal-info-wrapper" data-v-39576ba9 data-v-1aefc0b4><img src="/markdown-blog/wsqgif.gif" alt="author-avatar" class="personal-img" data-v-39576ba9> <h3 class="name" data-v-39576ba9>
    kasnars
  </h3> <div class="num" data-v-39576ba9><div data-v-39576ba9><h3 data-v-39576ba9>21</h3> <h6 data-v-39576ba9>Articles</h6></div> <div data-v-39576ba9><h3 data-v-39576ba9>14</h3> <h6 data-v-39576ba9>Tags</h6></div></div> <ul class="social-links" data-v-39576ba9></ul> <hr data-v-39576ba9></div> <nav class="nav-links"><div class="nav-item"><a href="/markdown-blog/" class="nav-link"><i class="iconfont reco-home"></i>
  主页
</a></div><div class="nav-item"><a href="/markdown-blog/timeline/" class="nav-link"><i class="iconfont reco-date"></i>
  时间轴
</a></div><div class="nav-item"><a href="/markdown-blog/tag/" class="nav-link"><i class="iconfont reco-tag"></i>
  标签
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>
      文档
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/theme-reco/" class="nav-link router-link-active"><i class="undefined"></i>
  前端知识点
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/computer/" class="nav-link"><i class="undefined"></i>
  计算机基础
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/docs/others/" class="nav-link"><i class="undefined"></i>
  其他技术栈
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-category"></i>
      分类
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/个人作品/" class="nav-link"><i class="undefined"></i>
  个人作品
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/解决方案/" class="nav-link"><i class="undefined"></i>
  解决方案
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/BUG记录/" class="nav-link"><i class="undefined"></i>
  BUG记录
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/技术整理/" class="nav-link"><i class="undefined"></i>
  技术整理
</a></li><li class="dropdown-item"><!----> <a href="/markdown-blog/categories/前端总结/" class="nav-link"><i class="undefined"></i>
  前端总结
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>
      链接
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://gitee.com/kasnars" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-mayun"></i>
  Gitee
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://juejin.cn/user/2287450072292567" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-juejin"></i>
  稀土掘金
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav> <ul class="sidebar-links"><li><a href="/markdown-blog/docs/theme-reco/htmlcss.html" class="sidebar-link">HTML+CSS知识点总结</a></li><li><a href="/markdown-blog/docs/theme-reco/js.html" class="sidebar-link">JavaScript知识点总结</a></li><li><a href="/markdown-blog/docs/theme-reco/ts.html" class="sidebar-link">TypeScript知识点总结</a></li><li><a href="/markdown-blog/docs/theme-reco/vue.html" class="sidebar-link">Vue知识点总结</a></li><li><a href="/markdown-blog/docs/theme-reco/react.html" aria-current="page" class="active sidebar-link">React知识点总结</a></li></ul> </aside> <div class="password-shadow password-wrapper-in" style="display:none;" data-v-25ba6db2 data-v-1aefc0b4><h3 class="title" data-v-25ba6db2 data-v-25ba6db2>React知识点总结</h3> <!----> <label id="box" class="inputBox" data-v-25ba6db2 data-v-25ba6db2><input type="password" value="" data-v-25ba6db2> <span data-v-25ba6db2>Konck! Knock!</span> <button data-v-25ba6db2>OK</button></label> <div class="footer" data-v-25ba6db2 data-v-25ba6db2><span data-v-25ba6db2><i class="iconfont reco-theme" data-v-25ba6db2></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-25ba6db2>vuePress-theme-reco</a></span> <span data-v-25ba6db2><i class="iconfont reco-copyright" data-v-25ba6db2></i> <a data-v-25ba6db2><span data-v-25ba6db2>kasnars</span>
            
          <span data-v-25ba6db2>2021 - </span>
          2024
        </a></span></div></div> <div data-v-1aefc0b4><main class="page" style="padding-right:0;"><section><div class="page-title"><h1 class="title">React知识点总结</h1> <div data-v-f875f3fc><i class="iconfont reco-account" data-v-f875f3fc><span data-v-f875f3fc>kasnars</span></i> <i class="iconfont reco-date" data-v-f875f3fc><span data-v-f875f3fc>2/9/2022</span></i> <i class="iconfont reco-eye" data-v-f875f3fc><span id="/markdown-blog/docs/theme-reco/react.html" data-flag-title="Your Article Title" class="leancloud-visitors" data-v-f875f3fc><a class="leancloud-visitors-count" style="font-size:.9rem;font-weight:normal;color:#999;"></a></span></i> <i class="tags iconfont reco-tag" data-v-f875f3fc><span class="tag-item" data-v-f875f3fc>React</span><span class="tag-item" data-v-f875f3fc>面经</span></i></div></div> <div class="theme-reco-content content__default"><h1 id="react知识点总结"><a href="#react知识点总结" class="header-anchor">#</a> React知识点总结</h1> <h2 id="组件基础"><a href="#组件基础" class="header-anchor">#</a> 组件基础</h2> <h3 id="react事件机制"><a href="#react事件机制" class="header-anchor">#</a> react事件机制</h3> <details class="custom-block details"><summary>答案</summary> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">handleClick</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">点我</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>React并不是将click事件绑定到了div的真实DOM上，而是在document处监听了所有的事件，当事件发生并且冒泡到document处的时候，React将事件内容封装并交由真正的处理函数运行。这样的方式不仅仅减少了内存的消耗，还能在组件挂在销毁时统一订阅和移除事件。</p></details> <h3 id="合成事件"><a href="#合成事件" class="header-anchor">#</a> 合成事件</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>JSX 上写的事件并没有绑定在对应的真实 DOM 上，而是通过事件代理的方式，将所有的事件都统一绑定在了 document 上。这样的方式不仅减少了内存消耗，还能在组件挂载销毁时统一订阅和移除事件。</li> <li>另外冒泡到 document 上的事件也不是原生浏览器事件，而是 React 自己实现的合成事件（SyntheticEvent）。因此我们如果不想要事件冒泡的话，调用 event.stopPropagation 是无效的，而应该调用 event.preventDefault。</li></ul></details> <h3 id="合成事件的目的"><a href="#合成事件的目的" class="header-anchor">#</a> 合成事件的目的</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>兼容所有浏览器，更好的跨平台；</li> <li>将事件统一存放在一个数组，避免频繁的新增与删除（垃圾回收）。</li> <li>方便 react 统一管理和事务机制。</li></ul></details> <h3 id="react的事件和普通原生事件有什么不同"><a href="#react的事件和普通原生事件有什么不同" class="header-anchor">#</a> React的事件和普通原生事件有什么不同</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>对于事件名称命名方式，原生事件为全小写，react 事件采用小驼峰；</li> <li>对于事件函数处理语法，原生事件为字符串，react 事件为函数；</li> <li>react 事件不能采用 return false 的方式来阻止浏览器的默认行为，而必须要地明确地调用preventDefault()来阻止默认行为。</li></ul></details> <h3 id="react事件与原生事件的执行顺序"><a href="#react事件与原生事件的执行顺序" class="header-anchor">#</a> React事件与原生事件的执行顺序</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>事件的执行顺序为原生事件先执行，合成事件后执行。</li> <li>合成事件会冒泡绑定到 document 上，所以尽量避免原生事件与合成事件混用，如果原生事件阻止冒泡，可能会导致合成事件不执行，因为需要冒泡到document 上合成事件才会执行。</li></ul></details> <h3 id="react-组件中怎么做事件代理-它的原理是什么"><a href="#react-组件中怎么做事件代理-它的原理是什么" class="header-anchor">#</a> React 组件中怎么做事件代理？它的原理是什么？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>React基于Virtual DOM实现了一个SyntheticEvent层（合成事件层），事件处理器会接收到一个合成事件对象的实例，所有的事件都自动绑定在最外层上。</li></ul></details> <h3 id="react底层对合成事件做了什么"><a href="#react底层对合成事件做了什么" class="header-anchor">#</a> React底层对合成事件做了什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>事件委派
<ul><li>React会把所有的事件绑定到结构的最外层，使用统一的事件监听器，这个事件监听器上维持了一个映射来保存所有组件内部事件监听和处理函数</li></ul></li> <li>自动绑定
<ul><li>React组件中，每个方法的上下文都会指向该组件的实例，即自动绑定this为当前组件。</li></ul></li></ul></details> <h3 id="hoc是什么"><a href="#hoc是什么" class="header-anchor">#</a> HOC是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>高阶组件（HOC）是 React 中用于复用组件逻辑的一种高级技巧。它是一种基于 React 的组合特性而形成的设计模式。</li> <li>简言之，HOC是一种组件的设计模式，HOC接受一个组件和额外的参数（如果需要），返回一个新的组件。HOC 是纯函数，没有副作用。</li></ul></details> <h3 id="hoc的优缺点"><a href="#hoc的优缺点" class="header-anchor">#</a> HOC的优缺点</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>优点∶ 逻辑服用、不影响被包裹组件的内部逻辑。</li> <li>缺点∶ hoc传递给被包裹组件的props容易和被包裹后的组件重名，进而被覆盖</li></ul></details> <h3 id="render-props是什么"><a href="#render-props是什么" class="header-anchor">#</a> Render props是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>&quot;render prop&quot;是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术 类似vue的props</li></ul></details> <h3 id="props的优缺点"><a href="#props的优缺点" class="header-anchor">#</a> props的优缺点</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>优点：数据共享、代码复用，将组件内的state作为props传递给调用者，将渲染逻辑交给调用者。</li> <li>缺点：无法在 return 语句外访问数据、多层嵌套写法不够优雅</li></ul></details> <h3 id="hook是什么"><a href="#hook是什么" class="header-anchor">#</a> Hook是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>Hook是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。通过自定义hook，可以复用代码逻辑。</li></ul></details> <h3 id="hook的优点"><a href="#hook的优点" class="header-anchor">#</a> Hook的优点</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>使用直观；</li> <li>解决hoc的prop 重名问题；</li> <li>解决render props 因共享数据 而出现嵌套地狱的问题；</li> <li>能在return之外使用数据的问题。</li></ul></details> <h3 id="component-element-instance-之间有什么区别和联系"><a href="#component-element-instance-之间有什么区别和联系" class="header-anchor">#</a> Component, Element, Instance 之间有什么区别和联系</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>元素
<ul><li>一个元素element是一个普通对象(plain object)，描述了对于一个DOM节点或者其他组件component，你想让它在屏幕上呈现成什么样子。元素element可以在它的属性props中包含其他元素(译注:用于形成元素树)。创建一个React元素element成本很低。元素element创建之后是不可变的</li></ul></li> <li>组件
<ul><li>一个组件component可以通过多种方式声明。可以是带有一个render()方法的类，简单点也可以定义为一个函数。这两种情况下，它都把属性props作为输入，把返回的一棵元素树作为输出。</li></ul></li> <li>实例
<ul><li>一个实例instance是你在所写的组件类component class中使用关键字this所指向的东西(译注:组件实例)。它用来存储本地状态和响应生命周期事件很有用。</li></ul></li> <li>函数式组件(Functional component)根本没有实例instance。类组件(Class component)有实例instance</li></ul></details> <h3 id="对componentwillreceiveprops-的理解"><a href="#对componentwillreceiveprops-的理解" class="header-anchor">#</a> 对componentWillReceiveProps 的理解</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>该方法当props发生变化时执行，初始化render时不执行，在这个回调函数里面，你可以根据属性的变化，通过调用this.setState()来更新你的组件状态，旧的属性还是可以通过this.props来获取,这里调用更新状态是安全的，并不会触发额外的render调用。</li> <li>一般用于父组件状态更新时子组件的重新渲染。</li></ul></details> <h3 id="哪些方法会触发react的重新渲染"><a href="#哪些方法会触发react的重新渲染" class="header-anchor">#</a> 哪些方法会触发React的重新渲染</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>setState()方法被调用 (传入的值为null的时候不会重新渲染)</li> <li>父组件重新渲染，只要父组件重新渲染，无论props是否变化，子组件都将重新渲染</li></ul></details> <h3 id="重新渲染时render会做些什么"><a href="#重新渲染时render会做些什么" class="header-anchor">#</a> 重新渲染时render会做些什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>会对新旧 VNode 进行对比，也就是我们所说的Diff算法</li> <li>对新旧两棵树进行一个深度优先遍历，这样每一个节点都会一个标记，在到深度遍历的时候，每遍历到一和个节点，就把该节点和新的节点树进行对比，如果有差异就放到一个对象里面</li> <li>遍历差异对象，根据差异的类型，根据对应对规则更新VNode</li></ul></details> <h3 id="react声明组件有哪几种方法"><a href="#react声明组件有哪几种方法" class="header-anchor">#</a> React声明组件有哪几种方法</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>函数式定义的无状态组件</li> <li>ES5原生方式React.createClass定义的组件(会自动绑定函数，导致不必要的性能开销)</li> <li>ES6形式的extends React.Component定义的组件</li></ul></details> <h3 id="有状态组件和无状态组件的区别和特点"><a href="#有状态组件和无状态组件的区别和特点" class="header-anchor">#</a> 有状态组件和无状态组件的区别和特点</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>有状态组件
<ul><li>是类组件</li> <li>有继承</li> <li>可以使用this</li> <li>可以使用react的生命周期</li> <li>内部使用 state，维护自身状态的变化，有状态组件根据外部组件传入的 props 和自身的 state进行渲染。</li></ul></li> <li>无状态组件
<ul><li>不依赖自身的状态state</li> <li>可以是类组件或者函数组件。</li> <li>可以完全避免使用 this 关键字。（由于使用的是箭头函数事件无需绑定）</li> <li>组件内部不维护 state ，只根据外部组件传入的 props 进行渲染的组件，当 props 改变时，组件重新渲染。</li></ul></li></ul></details> <h3 id="react里的fragment是什么"><a href="#react里的fragment是什么" class="header-anchor">#</a> React里的Fragment是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>React 中的一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组，而无需向 DOM 添加额外节点。</li> <li><em>即将其作为一个占位的标签，用来包裹内部所有元素使其变成一个大标签</em></li></ul></details> <h3 id="react如何获取页面内dom元素"><a href="#react如何获取页面内dom元素" class="header-anchor">#</a> React如何获取页面内dom元素</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>字符串格式：<div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">span</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div></li> <li>函数格式：<div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token parameter">ele</span> <span class="token operator">=&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>info <span class="token operator">=</span> ele<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
<span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> ref对应一个方法，并传一个参数作为节点的实例 <span class="token operator">--</span><span class="token operator">&gt;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div></li> <li>createRef()方法 React16<div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">MyComponent</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
    <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>myRef <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">createRef</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>myRef<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div></li></ul> <p>}
```</p></details> <h3 id="render阶段可以访问refs吗-为什么"><a href="#render阶段可以访问refs吗-为什么" class="header-anchor">#</a> render阶段可以访问refs吗？为什么？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>不能，render阶段里dom还未生成，获取需要在pre-commit阶段和commit阶段
<img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/98a52a67abd14d8cb2ba1fc00c0662a2~tplv-k3u1fbpfcp-watermark.awebp" alt=""></li></ul></details> <h3 id="react中受控组件与非受控组件是什么"><a href="#react中受控组件与非受控组件是什么" class="header-anchor">#</a> React中受控组件与非受控组件是什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>受控组件:在使用表单来收集用户输入时，例如<code>&lt;input&gt;&lt;select&gt;&lt;textearea&gt;</code>等元素都要绑定一个change事件，当表单的状态发生变化，就会触发onChange事件，更新组件的state。这种组件在React中被称为受控组件，</li> <li>非受控组件:如果一个表单组件没有value props（单选和复选按钮对应的是checked props）时，就可以称为非受控组件。在非受控组件中，可以使用一个ref来从DOM获得表单值。而不是为每个状态更新编写一个事件处理程序。</li></ul></details> <h3 id="react里的构造函数有什么用"><a href="#react里的构造函数有什么用" class="header-anchor">#</a> React里的构造函数有什么用</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>通过将对象分配给this.state来初始化本地状态</li> <li>将事件处理程序方法绑定到实例上</li></ul></details> <h2 id="数据管理"><a href="#数据管理" class="header-anchor">#</a> 数据管理</h2> <h3 id="react-setstate后发生了什么"><a href="#react-setstate后发生了什么" class="header-anchor">#</a> React setState后发生了什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>在 React 得到元素树之后，React 会自动计算出新的树与老树的节点差异，然后根据差异对界面进行最小化重渲染。</li> <li>如果在短时间内频繁setState。React会将state的改变压入栈中，在合适的时机，批量更新state和视图，达到提高性能的效果。</li></ul></details> <h3 id="setstate是同步还是异步"><a href="#setstate是同步还是异步" class="header-anchor">#</a> setState是同步还是异步</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>setState 并不是单纯同步/异步的，它的表现会因调用场景的不同而不同。。</li> <li>在源码中，通过 isBatchingUpdates 来判断setState 是先存进 state 队列还是直接更新，如果值为 true 则执行异步操作，为 false 则直接更新。
<ul><li>异步： 在 React 可以控制的地方，就为 true，比如在 React 生命周期事件和合成事件中，都会走合并操作，延迟更新的策略。</li> <li>同步： 在 React 无法控制的地方，比如原生事件，具体就是在 addEventListener 、setTimeout、setInterval 等事件中，就只能同步更新。</li></ul></li></ul></details> <h3 id="react中setstate的第二个参数作用是什么"><a href="#react中setstate的第二个参数作用是什么" class="header-anchor">#</a> React中setState的第二个参数作用是什么？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>setState 的第二个参数是一个可选的回调函数。这个回调函数将在组件重新渲染后执行。等价于在 componentDidUpdate 生命周期内执行</li></ul></details> <h3 id="react中的setstate和replacestate的区别是什么"><a href="#react中的setstate和replacestate的区别是什么" class="header-anchor">#</a> React中的setState和replaceState的区别是什么？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>setState 是修改其中的部分状态，相当于 Object.assign，只是覆盖，不会减少原来的状态。</li> <li>而replaceState 是完全替换原来的状态，相当于赋值，将原来的 state 替换为另一个对象，如果新状态属性减少，那么 state 中就没有这个状态了。</li></ul></details> <h2 id="生命周期"><a href="#生命周期" class="header-anchor">#</a> 生命周期</h2> <h3 id="react生命周期主要分成哪几个阶段"><a href="#react生命周期主要分成哪几个阶段" class="header-anchor">#</a> React生命周期主要分成哪几个阶段</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>装载阶段（Mount），组件第一次在DOM树中被渲染的过程；</li> <li>更新过程（Update），组件状态发生变化，重新更新渲染的过程；</li> <li>卸载过程（Unmount），组件从DOM树中被移除的过程；</li></ul></details> <h3 id="挂载阶段有哪些生命周期方法"><a href="#挂载阶段有哪些生命周期方法" class="header-anchor">#</a> 挂载阶段有哪些生命周期方法</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>constructor</li> <li>getDerivedStateFromProps</li> <li>render</li> <li>componentDidMount</li></ul></details> <h3 id="更新阶段有哪些生命周期方法"><a href="#更新阶段有哪些生命周期方法" class="header-anchor">#</a> 更新阶段有哪些生命周期方法</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>getDerivedStateFromProps</li> <li>shouldComponentUpdate</li> <li>render</li> <li>getSnapshotBeforeUpdate</li> <li>componentDidUpdate</li></ul></details> <h3 id="卸载阶段有哪些生命周期方法"><a href="#卸载阶段有哪些生命周期方法" class="header-anchor">#</a> 卸载阶段有哪些生命周期方法</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>componentWillUnmount()</li></ul></details> <h3 id="如果没有调用-setstate-props-值也没有变化-是不是组件就不会重新渲染"><a href="#如果没有调用-setstate-props-值也没有变化-是不是组件就不会重新渲染" class="header-anchor">#</a> 如果没有调用 setState，props 值也没有变化，是不是组件就不会重新渲染？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>会 只要不是null 无论值有没有变化都会重新渲染</li> <li>可以调用shouldComponentUpdate方法来控制更新后是否需要渲染，可以比较 this.props 和 nextProps ，this.state 和 nextState 值是否变化，来确认返回 true 或者 false</li></ul></details> <h3 id="组件卸载阶段用来干什么"><a href="#组件卸载阶段用来干什么" class="header-anchor">#</a> 组件卸载阶段用来干什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>清除 timer，取消网络请求或清除</li> <li>取消在 componentDidMount() 中创建的订阅等；</li></ul></details> <h3 id="react常见生命周期的运行流程"><a href="#react常见生命周期的运行流程" class="header-anchor">#</a> React常见生命周期的运行流程</h3> <details class="custom-block details"><summary>答案</summary> <ol><li>挂载阶段，首先执行constructor构造方法，来创建组件</li> <li>创建完成之后，就会执行render方法，该方法会返回需要渲染的内容</li> <li>随后，React会将需要渲染的内容挂载到DOM树上</li> <li>挂载完成之后就会执行componentDidMount生命周期函数</li> <li>如果我们给组件创建一个props（用于组件通信）、调用setState（更改state中的数据）、调用forceUpdate（强制更新组件）时，都会重新调用render函数</li> <li>render函数重新执行之后，就会重新进行DOM树的挂载</li> <li>挂载完成之后就会执行componentDidUpdate生命周期函数</li> <li>当移除组件时，就会执行componentWillUnmount生命周期函数</li></ol> <ul><li><em>constructor() -&gt; componentWillMount() -&gt; render() -&gt; componentDidMount()</em></li></ul></details> <h2 id="组件通信"><a href="#组件通信" class="header-anchor">#</a> 组件通信</h2> <h3 id="组件通信方式有哪些"><a href="#组件通信方式有哪些" class="header-anchor">#</a> 组件通信方式有哪些</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>⽗组件向⼦组件通讯: ⽗组件可以向⼦组件通过传 props 的⽅式，向⼦组件进⾏通讯</li> <li>⼦组件向⽗组件通讯: props+回调的⽅式，⽗组件向⼦组件传递props进⾏通讯，此props为作⽤域为⽗组件⾃身的函 数，⼦组件调⽤该函数，将⼦组件想要传递的信息，作为参数，传递到⽗组件的作⽤域中</li> <li>兄弟组件通信: 找到这两个兄弟节点共同的⽗节点,结合上⾯两种⽅式由⽗节点转发信息进⾏通信</li> <li>跨层级通信: Context 设计⽬的是为了共享那些对于⼀个组件树⽽⾔是“全局”的数据，例如当前认证的⽤户、主题或⾸选语⾔，对于跨越多层的全局数据通过 Context 通信再适合不过</li> <li>发布订阅模式: 发布者发布事件，订阅者监听事件并做出反应,我们可以通过引⼊event模块进⾏通信</li> <li>全局状态管理⼯具: 借助Redux或者Mobx等全局状态管理⼯具进⾏通信,这种⼯具会维护⼀个全局状态中⼼Store,并根据不同的事件产⽣新的状态</li></ul></details> <h2 id="路由"><a href="#路由" class="header-anchor">#</a> 路由</h2> <h3 id="react-router实现的思想"><a href="#react-router实现的思想" class="header-anchor">#</a> react-router实现的思想</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>基于 history 库来实现上述不同的客户端路由实现思想，并且能够保存历史记录等，磨平浏览器差异，上层无感知</li> <li>通过维护的列表，在每次 URL 发生变化的回收，通过配置的 路由路径，匹配到对应的 Component，并且 render</li></ul></details> <h3 id="如何配置-react-router-实现路由切换"><a href="#如何配置-react-router-实现路由切换" class="header-anchor">#</a> 如何配置 React-Router 实现路由切换</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>使用Route 组件</li></ul> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token comment">// when location = { pathname: '/about' }</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>/about<span class="token punctuation">'</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>About<span class="token punctuation">}</span></span><span class="token punctuation">/&gt;</span></span> <span class="token comment">// renders &lt;About/&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>/contact<span class="token punctuation">'</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>Contact<span class="token punctuation">}</span></span><span class="token punctuation">/&gt;</span></span> <span class="token comment">// renders null</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>Always<span class="token punctuation">}</span></span><span class="token punctuation">/&gt;</span></span> <span class="token comment">// renders &lt;Always/&gt;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div></details> <h3 id="react-router里的switch是什么"><a href="#react-router里的switch是什么" class="header-anchor">#</a> React-Router里的switch是什么</h3> <details class="custom-block details"><summary>答案</summary> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token comment">// &lt;Switch&gt; 用于将 &lt;Route&gt; 分组。</span>
<span class="token comment">//一个 &lt;Switch&gt; 会遍历其所有的子 &lt;Route&gt;元素，并仅渲染与当前地址匹配的第一个元素。</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Switch</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">exact</span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>Home<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/about<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>About<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/contact<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>Contact<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Switch</span></span><span class="token punctuation">&gt;</span></span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div></details> <h3 id="react-router怎么设置重定向"><a href="#react-router怎么设置重定向" class="header-anchor">#</a> React-Router怎么设置重定向？</h3> <details class="custom-block details"><summary>答案</summary> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token comment">// 使用&lt;Redirect&gt;组件实现路由的重定向：</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Switch</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Redirect</span></span> <span class="token attr-name">from</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>/users/:id<span class="token punctuation">'</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>/users/profile/:id<span class="token punctuation">'</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>/users/profile/:id<span class="token punctuation">'</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>Profile<span class="token punctuation">}</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Switch</span></span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div></details> <h3 id="react-router-里的-link-标签和-a-标签的区别"><a href="#react-router-里的-link-标签和-a-标签的区别" class="header-anchor">#</a> react-router 里的 Link 标签和 a 标签的区别</h3> <details class="custom-block details"><summary>答案</summary> <p>从最终渲染的 DOM 来看，这两者都是链接，都是 标签，区别是∶
&lt;Link&gt;是react-router 里实现路由跳转的链接，一般配合&lt;Router&gt; 使用，react-router接管了其默认的链接跳转行为，区别于传统的页面跳转，&lt;Link&gt; 的“跳转”行为只会触发相匹配的&lt;Router&gt;对应的页面内容更新，而不会刷新整个页面。</p></details> <h3 id="react-router中的link做了哪些事情"><a href="#react-router中的link做了哪些事情" class="header-anchor">#</a> react-router中的link做了哪些事情</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>有onclick那就执行onclick</li> <li>click的时候阻止a标签默认事件</li> <li>根据跳转href(即是to)，用history (web前端路由两种方式之一，history &amp; hash)跳转，此时只是链接变了，并没有刷新页面而a标签就是普通的超链接了，用于从当前页面跳转到href指向的另一 个页面(非锚点情况)。</li></ul></details> <h3 id="react-router如何获取url的参数"><a href="#react-router如何获取url的参数" class="header-anchor">#</a> React-Router如何获取URL的参数？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>get传值：
<ul><li>路由配置还是普通的配置，如：'admin'，传参方式如：'admin?id='1111''。通过this.props.location.search获取url获取到一个字符串'?id='1111'
可以用url，qs，querystring，浏览器提供的api URLSearchParams对象或者自己封装的方法去解析出id的值。</li></ul></li> <li>动态路由传值
<ul><li>路由需要配置成动态路由：如path='/admin/:id'，传参方式，如'admin/111'。通过this.props.match.params.id 取得url中的动态路由id部分的值，除此之外还可以通过useParams（Hooks）来获取</li></ul></li> <li>通过query或state传值
<ul><li>{pathname:'/admin',query:'111',state:'111'};。通过this.props.location.state或this.props.location.query来获取即可，传递的参数可以是对象、数组等，但是存在缺点就是只要刷新页面，参数就会丢失。</li></ul></li></ul></details> <h3 id="react-router获取历史对象"><a href="#react-router获取历史对象" class="header-anchor">#</a> React-Router获取历史对象</h3> <details class="custom-block details"><summary>答案</summary> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code>BrowserRouter 创建的 <span class="token constant">URL</span> 格式：xxx<span class="token punctuation">.</span>com<span class="token operator">/</span>path
HashRouter 创建的 <span class="token constant">URL</span> 格式：xxx<span class="token punctuation">.</span>com<span class="token operator">/</span>#<span class="token operator">/</span>path
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div></details> <h3 id="react-router实现精准匹配"><a href="#react-router实现精准匹配" class="header-anchor">#</a> react-router实现精准匹配</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>exact</li></ul> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token comment">// exact属性：它的作用就是精确匹配路径，经常与&lt;Switch&gt; 联合使用。只有当 URL 和该 &lt;Route&gt; 的 path 属性完全一致的情况下才能匹配上</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> Switch<span class="token punctuation">,</span> Route<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-router-dom'</span>
   
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Switch</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
   </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">exact</span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>Home<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
   </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Route</span></span> <span class="token attr-name">exact</span> <span class="token attr-name">path</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/login<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>Login<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Route</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Switch</span></span><span class="token punctuation">&gt;</span></span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div></details> <h2 id="redux"><a href="#redux" class="header-anchor">#</a> Redux</h2> <h3 id="对redux的理解-redux主要拿来做什么"><a href="#对redux的理解-redux主要拿来做什么" class="header-anchor">#</a> 对Redux的理解，Redux主要拿来做什么</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>Redux是一个用来管理数据状态和UI状态的JavaScript应用工具。随着JavaScript单页应用（SPA）开发日趋复杂， JavaScript需要管理比任何时候都要多的state（状态）， Redux就是降低管理难度的。</li> <li>单纯的Redux只是一个状态机，是没有UI呈现的，react- redux作用是将Redux的状态机和React的UI呈现绑定在一起，当你dispatch action改变state的时候，会自动更新页面。</li></ul></details> <h3 id="redux工作流程"><a href="#redux工作流程" class="header-anchor">#</a> Redux工作流程</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>const store= createStore（fn）生成数据;</li> <li>action: {type: Symble('action01), payload:'payload' }定义行为;</li> <li>dispatch发起action：store.dispatch(doSomething('action001'));</li> <li>reducer：处理action，返回新的state;</li></ul> <hr> <p>通俗解释</p> <ul><li>首先，用户（通过View）发出Action，发出方式就用到了dispatch方法</li> <li>然后，Store自动调用Reducer，并且传入两个参数：当前State和收到的Action，Reducer会返回新的State</li> <li>State—旦有变化，Store就会调用监听函数，来更新View</li></ul></details> <h3 id="redux中异步请求如何处理"><a href="#redux中异步请求如何处理" class="header-anchor">#</a> Redux中异步请求如何处理</h3> <details class="custom-block details"><summary>答案</summary> <p>借助异步中间件</p> <ol><li>redux-thunk</li> <li>redux-saga</li></ol></details> <h3 id="redux-怎么实现属性传递-介绍下原理"><a href="#redux-怎么实现属性传递-介绍下原理" class="header-anchor">#</a> Redux 怎么实现属性传递，介绍下原理</h3> <details class="custom-block details"><summary>答案</summary> <p>react-redux 数据传输∶ view--&gt;action--&gt;reducer--&gt;store--&gt;view</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>view 上的AddClick 事件通过mapDispatchToProps 把数据传到action ---&gt; click:()=&gt;dispatch(ADD)
action 的ADD 传到reducer上
reducer传到store上 const store = createStore(reducer);
store再通过 mapStateToProps 映射穿到view上text:State.text
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div></details> <h3 id="redux-中间件是什么"><a href="#redux-中间件是什么" class="header-anchor">#</a> Redux 中间件是什么？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>Redux 的中间件提供的是位于 action 被发起之后，到达 reducer 之前的扩展点</li></ul> <blockquote><p>增加前</p> <blockquote><p>view -→&gt; action -&gt; reducer -&gt; store</p></blockquote></blockquote> <blockquote><p>增加后</p> <blockquote><p>view -&gt; action -&gt; middleware -&gt; reducer -&gt; store</p></blockquote></blockquote> <ul><li>在这一环节可以做一些&quot;副作用&quot;的操作，如异步请求、打印日志等。</li></ul></details> <h3 id="redux-状态管理器和变量挂载到-window-中有什么区别"><a href="#redux-状态管理器和变量挂载到-window-中有什么区别" class="header-anchor">#</a> Redux 状态管理器和变量挂载到 window 中有什么区别</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>两者都是存储数据以供后期使用。但是Redux状态更改可回溯——Time travel，数据多了的时候可以很清晰的知道改动在哪里发生，完整的提供了一套状态管理模式。</li></ul></details> <h3 id="mobox-和-redux-有什么区别"><a href="#mobox-和-redux-有什么区别" class="header-anchor">#</a> mobox 和 redux 有什么区别？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>共同点
<ul><li>为了解决状态管理混乱，无法有效同步的问题统一维护管理应用状态;</li> <li>某一状态只有一个可信数据来源（通常命名为store，指状态容器）;</li> <li>操作更新状态方式统一，并且可控（通常以action方式提供更新状态的途径）;</li> <li>支持将store与React组件连接，如react-redux，mobx- react;</li></ul></li></ul> <hr> <ul><li>不同点
<ul><li>redux将数据保存在单一的store中，mobx将数据保存在分散的多个store中</li> <li>redux使用plain object保存数据，需要手动处理变化后的操作;mobx适用observable保存数据，数据变化后自动处理响应的操作</li> <li>redux使用不可变状态，这意味着状态是只读的，不能直接去修改它，而是应该返回一个新的状态，同时使用纯函数;mobx中的状态是可变的，可以直接对其进行修改</li> <li>mobx相对来说比较简单，在其中有很多的抽象，mobx更多的使用面向对象的编程思维;redux会比较复杂，因为其中的函数式编程思想掌握起来不是那么容易，同时需要借助一系列的中间件来处理异步和副作用</li> <li>mobx中有更多的抽象和封装，调试会比较困难，同时结果也难以预测;而redux提供能够进行时间回溯的开发工具，同时其纯函数以及更少的抽象，让调试变得更加的容易</li></ul></li></ul></details> <h3 id="redux和vuex的相同与不同"><a href="#redux和vuex的相同与不同" class="header-anchor">#</a> Redux和vuex的相同与不同</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>区别
<ul><li>Vuex改进了Redux中的Action和Reducer函数，以mutations变化函数取代Reducer，无需switch，只需在对应的mutation函数里改变state值即可</li> <li>Vuex由于Vue自动重新渲染的特性，无需订阅重新渲染函数，只要生成新的State即可</li></ul></li> <li>共同点
<ul><li>单—的数据源</li> <li>变化可以预测</li> <li>redux与vuex都是对mvvm思想的服务，将数据从视图中抽离的一种方案。</li></ul></li></ul></details> <h2 id="hooks"><a href="#hooks" class="header-anchor">#</a> Hooks</h2> <h3 id="为什么-usestate-要使用数组而不是对象"><a href="#为什么-usestate-要使用数组而不是对象" class="header-anchor">#</a> 为什么 useState 要使用数组而不是对象</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>如果 useState 返回的是数组，那么使用者可以对数组中的元素命名，代码看起来也比较干净</li> <li>如果 useState 返回的是对象，在解构对象的时候必须要和 useState 内部实现返回的对象同名，想要使用多次的话，必须得设置别名才能使用返回值</li></ul></details> <h3 id="react-hooks-解决了哪些问题"><a href="#react-hooks-解决了哪些问题" class="header-anchor">#</a> React Hooks 解决了哪些问题？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>在组件之间复用状态逻辑很难</li> <li>复杂组件变得难以理解</li> <li>难以理解的 class</li></ul></details> <h3 id="react-hook-的使用限制有哪些"><a href="#react-hook-的使用限制有哪些" class="header-anchor">#</a> React Hook 的使用限制有哪些？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>不要在循环、条件或嵌套函数中调用 Hook；</li> <li>必须在 React 的函数组件中调用 Hook。</li></ul> <p><em>因为 Hooks 的设计是基于数组实现。在调用时按顺序加入数组中，如果使用循环、条件或嵌套函数很有可能导致数组取值错位，执行错误的 Hook。当然，实质上 React 的源码里不是数组，是链表。</em></p></details> <h3 id="useeffect-与-uselayouteffect-的相同与不同"><a href="#useeffect-与-uselayouteffect-的相同与不同" class="header-anchor">#</a> useEffect 与 useLayoutEffect 的相同与不同</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>useEffect 与 useLayoutEffect 两者都是用于处理副作用</li> <li>useEffect 在 React 的渲染过程中是被异步调用的，用于绝大多数场景；而 useLayoutEffect 会在所有的 DOM 变更之后同步调用，主要用于处理 DOM 操作、调整样式、避免页面闪烁等问题。也正因为是同步处理，所以需要避免在 useLayoutEffect 做计算量较大的耗时任务从而造成阻塞。<br> <em>useLayoutEffect总是比useEffect先执行</em></li></ul></details> <h3 id="使用usestate时候-使用push-pop-splice等直接更改数组对象的坑"><a href="#使用usestate时候-使用push-pop-splice等直接更改数组对象的坑" class="header-anchor">#</a> 使用useState时候，使用push，pop，splice等直接更改数组对象的坑</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>使用push直接更改数组无法获取到新值，应该采用析构方式(...arr, newItem)</li></ul> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">function</span> <span class="token function">Indicatorfilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> <span class="token punctuation">[</span>num<span class="token punctuation">,</span>setNums<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> <span class="token function-variable function">test</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 这里坑是直接采用push去更新num</span>
    <span class="token comment">// setNums(num)是无法更新num的</span>
    <span class="token comment">// 必须使用num = [...num ,1]</span>
    num<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token comment">// num = [...num ,1]</span>
    <span class="token function">setNums</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>filter<span class="token punctuation">'</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>test<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">测试</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
          </span><span class="token punctuation">{</span>num<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span>index</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>item<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
          <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div></details> <h2 id="虚拟dom"><a href="#虚拟dom" class="header-anchor">#</a> 虚拟dom</h2> <h3 id="为什么要用虚拟dom"><a href="#为什么要用虚拟dom" class="header-anchor">#</a> 为什么要用虚拟dom</h3> <details class="custom-block details"><summary>答案</summary> <ol><li>保证性能下限，在不进行手动优化的情况下，提供过得去的性能</li> <li>跨平台 Virtual DOM本质上是JavaScript的对象，它可以很方便的跨平台操作，比如服务端渲染、uniapp等。</li></ol></details> <h3 id="react-diff算法的流程"><a href="#react-diff算法的流程" class="header-anchor">#</a> React Diff算法的流程</h3> <details class="custom-block details"><summary>答案</summary> <ol><li>真实的 DOM 首先会映射为虚拟 DOM；</li> <li>当虚拟 DOM 发生变化后，就会根据差距计算生成 patch，这个 patch 是一个结构化的数据，内容包含了增加、更新、移除等；</li> <li>根据 patch 去更新真实的 DOM，反馈到用户的界面上。<br> <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/246e03a02e3e48ff941f921843bd8676~tplv-k3u1fbpfcp-watermark.awebp" alt="diff算法流程"></li></ol></details> <h3 id="react-diff算法优化策略"><a href="#react-diff算法优化策略" class="header-anchor">#</a> react diff算法优化策略</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>策略一：忽略节点跨层级操作场景，提升比对效率。（基于树进行对比）</li> <li>策略二：如果组件的 class 一致，则默认为相似的树结构，否则默认为不同的树结构。（基于组件进行对比）</li> <li>策略三：同一层级的子节点，可以通过标记 key 的方式进行列表对比。（基于节点进行对比）</li></ul></details> <h3 id="react-key是做什么的-为什么需要key"><a href="#react-key是做什么的-为什么需要key" class="header-anchor">#</a> react key是做什么的？为什么需要key</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。在开发过程中，我们需要保证某个元素的 key 在其同级元素中具有唯一性。</li></ul></details> <h3 id="react和vue的diff算法有何不同"><a href="#react和vue的diff算法有何不同" class="header-anchor">#</a> react和vue的diff算法有何不同</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>自 React 16 起，引入了 Fiber 架构。为了使整个更新过程可随时暂停恢复，节点与树分别采用了 FiberNode 与 FiberTree 进行重构。fiberNode 使用了双链表的结构，可以直接找到兄弟节点与子节点。整个更新过程由 current 与 workInProgress 两株树双缓冲完成。workInProgress 更新完成后，再通过修改 current 相关指针指向新节点。</li> <li>Vue 的整体 diff 策略与 React 对齐，虽然缺乏时间切片能力，但这并不意味着 Vue 的性能更差，因为在 Vue 3 初期引入过，后期因为收益不高移除掉了。除了高帧率动画，在 Vue 中其他的场景几乎都可以使用防抖和节流去提高响应性能。</li></ul></details> <h2 id="其他"><a href="#其他" class="header-anchor">#</a> 其他</h2> <h3 id="如何实现数据持久化"><a href="#如何实现数据持久化" class="header-anchor">#</a> 如何实现数据持久化</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>redux-persist。redux-persist会将redux的store中的数据缓存到浏览器的localStorage中。</li></ul></details> <h3 id="对比一下vue和react"><a href="#对比一下vue和react" class="header-anchor">#</a> 对比一下vue和react</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>相同
<ul><li>都将注意力集中保持在核心库，而将其他功能如路由和全局状态管理交给相关的库</li> <li>都有自己的构建工具，能让你得到一个根据最佳实践设置的项目模板。</li> <li>都使用了Virtual DOM（虚拟DOM）提高重绘性能</li> <li>都有props的概念，允许组件间的数据传递</li> <li>都鼓励组件化应用，将应用分拆成一个个功能明确的模块，提高复用性</li></ul></li> <li>不同
<ul><li>Vue默认支持数据双向绑定，而React一直提倡单向数据流</li> <li>Vue宣称可以更快地计算出Virtual DOM的差异，这是由于它在渲染过程中，会跟踪每一个组件的依赖关系，不需要重新渲染整个组件树。</li> <li>对于React而言，每当应用的状态被改变时，全部子组件都会重新渲染。当然，这可以通过 PureComponent/shouldComponentUpdate这个生命周期方法来进行控制，但Vue将此视为默认的优化。</li> <li>Vue鼓励写近似常规HTML的模板。写起来很接近标准 HTML元素，只是多了一些属性。React推荐你所有的模板通用JavaScript的语法扩展——JSX书写。</li> <li>Vue 通过 getter/setter 以及一些函数的劫持，能精确知道数据变化，不需要特别的优化就能达到很好的性能</li> <li>React 默认是通过比较引用的方式进行的，如果不优化（PureComponent/shouldComponentUpdate）可能导致大量不必要的vDOM的重新渲染。这是因为 Vue 使用的是可变数据，而React更强调数据的不可变。</li> <li>react可以通过高阶组件（Higher Order Components-- HOC）来扩展，而vue需要通过mixins来扩展。</li></ul></li></ul></details> <h3 id="react的状态提升是什么"><a href="#react的状态提升是什么" class="header-anchor">#</a> React的状态提升是什么？</h3> <details class="custom-block details"><summary>答案</summary> <ul><li>将多个组件需要共享的状态提升到它们最近的父组件上，在父组件上改变这个状态然后通过props分发给子组件。</li></ul></details> <p><em>该页面数据由本人编写+网上论坛整理所得</em></p> <p><em>参考数据地址</em></p> <ul><li><a href="https://juejin.cn/post/6941546135827775525" target="_blank" rel="noopener noreferrer">「2021」高频前端面试题汇总之React篇（上） -CUGGZ<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.cn/post/6940942549305524238" target="_blank" rel="noopener noreferrer">「2021」高频前端面试题汇总之React篇（下） -CUGGZ<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></section> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">Last Updated: </span> <span class="time">2/22/2022, 11:29:59 PM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev"><a href="/markdown-blog/docs/theme-reco/vue.html" class="prev">
            Vue知识点总结
          </a></span> <!----></p></div> <div class="comments-wrapper"><!----></div> <ul class="side-bar sub-sidebar-wrapper" style="width:0;" data-v-cb1513f6></ul></main> <!----></div></div></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-c6073ba8 data-v-c6073ba8><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-c6073ba8><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-c6073ba8></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-c6073ba8></path></svg></div></div></div>
    <script src="/markdown-blog/assets/js/app.4ad08097.js" defer></script><script src="/markdown-blog/assets/js/3.ddd67056.js" defer></script><script src="/markdown-blog/assets/js/1.7a25059f.js" defer></script><script src="/markdown-blog/assets/js/29.f6bd6a28.js" defer></script>
  </body>
</html>
